package com.mall.common.service.impl;

import static com.mall.common.Constants.OPERATE_TYPE_AUTHORITY;
import static com.mall.common.Constants.OPERATE_TYPE_NORMAL;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mall.common.dao.RoleDao;
import com.mall.common.domain.manage.Menu;
import com.mall.common.domain.manage.Operate;
import com.mall.common.domain.manage.Role;
import com.mall.common.hibernate.Finder;
import com.mall.common.service.OperateService;
import com.mall.common.service.RoleService;

/**
 * Service实现类 - 角色
 */

@Service
@Transactional(readOnly=true)
public class RoleServiceImpl extends BaseServiceImpl<Role, Long> implements RoleService {
	
	@Resource OperateService operateService;
	
	@Resource
	public void setBaseDao(RoleDao roleDao) {
		super.setBaseDao(roleDao);
	}
	
	public List<Operate> getAuthOperate(Long[] roleIds){
		Finder f = Finder.create("selecte o from Role r join r.operateSet o where r.id in (:roleIds)");
		f.setParamList("roleIds", roleIds);
		return f.findHQLList();
	}
	
	@Override
	public List<Menu> getPrivMenu(String[] roleIds){
		Finder f = Finder.create("select bean from Menu bean");
		f.append(" join bean.roleSet role");
		f.append(" where 1=1");
		
		if(roleIds != null && roleIds.length > 0){
			f.append(" and role.id in (:roleIds)");
			f.setParamList("roleIds", roleIds);
		}
		return f.findHQLList();
	}
	
	@Override
	public List<Operate> getPrivOperate(String[] roleIds, Menu menu, Boolean isDiaplayInToolBar){
		Finder f = Finder.create("select bean from Operate bean");
		f.append(" join bean.roleSet role where 1=1");
		if(roleIds != null && roleIds.length > 0){
			f.append(" and role.id in (:roleIds)");
			f.setParamList("roleIds", roleIds);
		}
		
		if(menu != null && menu.getId() != null){
			f.append(" and bean.menu=:menu");
			f.setParam("menu", menu);
		}
		
		if(isDiaplayInToolBar != null){
			f.append(" and bean.isDiaplayInToolBar=:isDiaplayInToolBar");
			f.setParam("isDiaplayInToolBar", isDiaplayInToolBar);
		}
		return f.findHQLList();
	}
	
	@Override
	@Transactional(readOnly=true)
	public List<Operate> getAutOperate(Menu menu){
		Finder f = Finder.create("select bean from Operate bean");
		f.append(" where bean.type=:type");
		f.setParam("type", OPERATE_TYPE_AUTHORITY);
		if(menu != null && menu.getId() != null){
			f.append(" and bean.menu=:menu");
			f.setParam("menu", menu);
		}
		return f.findHQLList();
	}
	
	@Override
	public List<Menu> getNormalOperate(Menu menu){
		Finder f = Finder.create("select bean from Operate bean");
		f.append(" where bean.type=:type");
		f.setParam("type", OPERATE_TYPE_NORMAL);
		if(menu != null && menu.getId() != null){
			f.append(" and bean.menu=:menu");
			f.setParam("menu", menu);
		}
		return f.findHQLList();
	}
	
	public List<String> getPrivMenuIds(String[] roleIds){
		Finder f = Finder.create("select bean.id from Menu bean");
		f.append(" join bean.roleSet role");
		f.append(" where 1=1");
		
		if(roleIds != null && roleIds.length > 0){
			f.append(" and role.id in (:roleIds)");
			f.setParamList("roleIds", roleIds);
		}
		return f.findHQLList();
	}
	
	public List<String> getPrivOperateIds(String[] roleIds){
		Finder f = Finder.create("select bean.id from Operate bean");
		f.append(" join bean.roleSet role where 1=1");
		
		if(roleIds != null && roleIds.length > 0){
			f.append(" and role.id in (:roleIds)");
			f.setParamList("roleIds", roleIds);
		}
		return f.findHQLList();
	}
	
	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public Role editRoleMenu(Role entity, Long[] menuIds, Long[] operateIds) {
		Set<Menu> menuSet = new HashSet<Menu>();
		for(int i=0; i<menuIds.length; i++){
			Menu menu = new Menu();
			menu.setId(menuIds[i]);
			menuSet.add(menu);
		}
		
		Set<Operate> operateSet = new HashSet<Operate>();
		for(int i=0; i<operateIds.length; i++){
			if(operateIds[i] == null){
				continue;
			}
			Operate operate = new Operate();
			operate.setId(operateIds[i]);
			operateSet.add(operate);
		}
		entity.setMenuSet(menuSet);
		entity.setOperateSet(operateSet);
		super.update(entity);
		return entity;
	}
	
	@Override
	public List<Role> getRolesByIds(Long[] ids){
		String hql = "from Role r where r.id in (:roleIds)";
		Finder finder = Finder.create(hql);
		finder.setParamList("roleIds", ids);
		return finder.findHQLList();
	}
	
	@Override
	public List<Role> getRolesFilterByIds(Long[] ids){
		String hql = "from Role r where r.id not in (:roleIds)";
		Finder finder = Finder.create(hql);
		finder.setParamList("roleIds", ids);
		return finder.findHQLList();
	}

	@Override
	public List<Operate> getAuthOperate(Long userId) {
		return null;
	}

	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void persist(Role entity) {
		super.persist(entity);
	}

	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void remove(Long[] ids) {
		super.remove(ids);
	}

	@Override
	@CacheEvict(value="authorization",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public Role update(Role entity) {
		return super.update(entity);
	}
	
}